#ifndef MDTX_USE_RCPPARMADILLO
#define MDTX_USE_RCPPARMADILLO
#endif

#include <RcppArmadillo.h>
using namespace Rcpp;

#include "mdtx-online/indicator/indicator_type_ma.h"
#include "mdtx-online/indicator/indicator_type_ma_macd.h"
using namespace mdtx::online;

#include "indi_common.h"

using macd_ = indi3<indicator::macd<indicator::ema>>;

//' Moving average convergence/divergence
//'
//' @param x Numeric vector to calculate MACD
//' @param short_period Fast period, usually 12
//' @param long_period Slow period, usually 26
//' @param signal_period Signal period, usually 9
//' @return List of MACD, Signal and Histogram
//' @export
// [[Rcpp::export(rng = false)]]
List macd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = macd_::create_t(short_period, long_period, signal_period);
    auto ans = macd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP macd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return macd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List macd_run(SEXP ptr, NumericVector x)
{
    auto ans = macd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using tmacd_ = indi3<indicator::macd<indicator::tma>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List tmacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = tmacd_::create_t(short_period, long_period, signal_period);
    auto ans = tmacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP tmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return tmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List tmacd_run(SEXP ptr, NumericVector x)
{
    auto ans = tmacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using wmacd_ = indi3<indicator::macd<indicator::wma>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List wmacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = wmacd_::create_t(short_period, long_period, signal_period);
    auto ans = wmacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP wmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return wmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List wmacd_run(SEXP ptr, NumericVector x)
{
    auto ans = wmacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using hmacd_ = indi3<indicator::macd<indicator::hma>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List hmacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = hmacd_::create_t(short_period, long_period, signal_period);
    auto ans = hmacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP hmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return hmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List hmacd_run(SEXP ptr, NumericVector x)
{
    auto ans = hmacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using demacd_ = indi3<indicator::macd<indicator::dema>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List demacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = demacd_::create_t(short_period, long_period, signal_period);
    auto ans = demacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP demacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return demacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List demacd_run(SEXP ptr, NumericVector x)
{
    auto ans = demacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using temacd_ = indi3<indicator::macd<indicator::tema>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List temacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = temacd_::create_t(short_period, long_period, signal_period);
    auto ans = temacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP temacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return temacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List temacd_run(SEXP ptr, NumericVector x)
{
    auto ans = temacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using t3macd_ = indi3<indicator::macd<indicator::t3ma>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List t3macd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = t3macd_::create_t(short_period, long_period, signal_period);
    auto ans = t3macd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP t3macd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return t3macd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List t3macd_run(SEXP ptr, NumericVector x)
{
    auto ans = t3macd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using ewmacd_ = indi3<indicator::macd<indicator::ewma>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List ewmacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = ewmacd_::create_t(short_period, long_period, signal_period);
    auto ans = ewmacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP ewmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return ewmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List ewmacd_run(SEXP ptr, NumericVector x)
{
    auto ans = ewmacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using zlemacd_ = indi3<indicator::macd<indicator::zlema>>;

//' @rdname macd
//' @export
// [[Rcpp::export(rng = false)]]
List zlemacd(NumericVector x, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    auto c = zlemacd_::create_t(short_period, long_period, signal_period);
    auto ans = zlemacd_::run_t(c, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP zlemacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return zlemacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List zlemacd_run(SEXP ptr, NumericVector x)
{
    auto ans = zlemacd_::run(ptr, x);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using vwmacd_ = indi3<indicator::wmacd<indicator::vwma>>;

//' Volume weighted moving average convergence/divergence
//'
//' @param price Numeric vector price
//' @param volume Numeric vector volume
//' @param short_period Fast period, usually 12
//' @param long_period Slow period, usually 26
//' @param signal_period Signal period, usually 9
//' @return List of MACD, Signal and Histogram
//' @export
// [[Rcpp::export(rng = false)]]
List vwmacd(NumericVector price, NumericVector volume, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    if (price.length() != volume.length())
    {
        stop("Input lengths do not match.");
    }
    auto c = vwmacd_::create_t(short_period, long_period, signal_period);
    auto ans = vwmacd_::run_t(c, price, volume);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP vwmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return vwmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List vwmacd_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    auto ans = vwmacd_::run(ptr, price, volume);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

using evwmacd_ = indi3<indicator::wmacd<indicator::evwma>>;

//' @rdname vwmacd
//' @export
// [[Rcpp::export(rng = false)]]
List evwmacd(NumericVector price, NumericVector volume, int short_period = 12, int long_period = 26, int signal_period = 9)
{
    if (price.length() != volume.length())
    {
        stop("Input lengths do not match.");
    }
    auto c = evwmacd_::create_t(short_period, long_period, signal_period);
    auto ans = evwmacd_::run_t(c, price, volume);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}

// [[Rcpp::export(rng = false)]]
SEXP evwmacd_new(int short_period = 12, int long_period = 26, int signal_period = 9)
{
    return evwmacd_::create(short_period, long_period, signal_period);
}

// [[Rcpp::export(rng = false)]]
List evwmacd_run(SEXP ptr, NumericVector price, NumericVector volume)
{
    auto ans = evwmacd_::run(ptr, price, volume);
    ans.names() = CharacterVector::create("MACD", "signal", "histo");
    return ans;
}
